﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace MysqlWindowsService
{
    public partial class MysqlWindowsService : ServiceBase
    {
        public MysqlWindowsService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
       // public  void OnStart()
        {
            var vc2013Name = @"Microsoft Visual C++ 2013 Redistributable";
            if (!IsInstalledFromRegistry(vc2013Name))
            {
                Common.WriteLog("VcEnvironmentJudgment start");
                Process frpProcess = new Process();
                frpProcess.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + "vc_runtime.exe";
                frpProcess.StartInfo.Arguments = " /VERYSILENT /NORESTART /SUPPRESSMSGBOXES ";
                frpProcess.StartInfo.CreateNoWindow = true;
                frpProcess.StartInfo.UseShellExecute = false;
                // Guardian to restart
                frpProcess.EnableRaisingEvents = true;
                frpProcess.Exited += new EventHandler(ExitProcess);
                // The process output
                frpProcess.StartInfo.RedirectStandardOutput = true;
                frpProcess.StartInfo.RedirectStandardError = true;
                frpProcess.OutputDataReceived += new DataReceivedEventHandler(MyProcOutputHandler);
                frpProcess.ErrorDataReceived += new DataReceivedEventHandler(MyProcOutputHandler);
                frpProcess.Start();
                frpProcess.BeginOutputReadLine();
                frpProcess.BeginErrorReadLine();
            }
            else
            {
                ReIinstallMysql();
            }
          /*  System.Timers.Timer mysqlTimer = new System.Timers.Timer();
            mysqlTimer.Interval = 7*1000;
            mysqlTimer.Enabled = true;
            mysqlTimer.Elapsed += new System.Timers.ElapsedEventHandler(MysqlTimerEvent);*/
        }

        #region exit install vc  process and install mysql service
        private void ExitProcess(Object sender = null, EventArgs e = null)
        {
            Common.WriteLog(" vc runtime install finish!!! ");
            ReIinstallMysql();
        }

        #endregion
        #region write log
        private static void WriteLog(string logStr, bool wTime = true)
        {
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\MysqlService.log", true))
            {
                string timeStr = wTime == true ? DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss ") : "";
                sw.WriteLine(timeStr + logStr);
            }
        }
        #endregion
        protected override void OnStop()
        {
            WriteLog("  OnStop  start  ", true);
            Process proc = new Process();
            proc.StartInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;
            proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.FileName = "cmd.exe";
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.RedirectStandardInput = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.Start();
            // proc.StandardInput.WriteLine( "cd " + AppDomain.CurrentDomain.BaseDirectory);
            WriteLog("cd " + AppDomain.CurrentDomain.BaseDirectory, true);
            proc.StandardInput.WriteLine("net stop MysqlWindowsService ");
            proc.StandardInput.WriteLine("exit");
            while (!proc.StandardOutput.EndOfStream)
            {
                string line = proc.StandardOutput.ReadLine();
                WriteLog(line, true);
            }
            WriteLog("  OnStop  end  ", true);
        }
        public static bool IsServiceExisted(string serviceName)
        {
            ServiceController[] services = ServiceController.GetServices();
            foreach (ServiceController sc in services)
            {
                if (sc.ServiceName.ToLower() == serviceName.ToLower())
                {
                    return true;
                }
            }
            return false;
        }


        #region out put process message 
        private void MyProcOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            if (!String.IsNullOrEmpty(outLine.Data))
            {
                Common.WriteLog(outLine.Data);

            }
        }
        #endregion

        #region install mysql 
        public static void InstallMysqlService()
        {
            Common.WriteLog(" install MysqlWindowsService start");
            Process proc = new Process();
            proc.StartInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory ;
            proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.FileName = "cmd.exe";
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.RedirectStandardInput = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.Start();
            // proc.StandardInput.WriteLine( "cd " + AppDomain.CurrentDomain.BaseDirectory);
            Common.WriteLog("cd " + AppDomain.CurrentDomain.BaseDirectory);
            proc.StandardInput.WriteLine(" mysql_init_db.bat ");
            proc.StandardInput.WriteLine("exit");
            while (!proc.StandardOutput.EndOfStream)
            {
                string line = proc.StandardOutput.ReadLine();
                Common.WriteLog(line);
            }
            Common.WriteLog(" install MysqlWindowsService end");
        }
        #endregion

        #region Determines whether the registry service exists
        public static bool IsInstalledFromRegistry(string displayName)
        {
            var registryPath = @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registryPath, false))
            {
                foreach (var keyName in key.GetSubKeyNames())
                {
                    if (string.IsNullOrEmpty(keyName))
                    {
                        continue;
                    }
                    using (var subKey = key.OpenSubKey(keyName, false))
                    {
                        if (subKey == null)
                        {
                            continue;
                        }
                        var name = subKey.GetValue("DisplayName");
                        if (name != null && name.ToString().StartsWith(displayName))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        #endregion
        public static void ReIinstallMysql()
        {

            if (!Common.IsServiceExisted("MysqlWindowsService"))
            {
                Common.WriteLog("MysqlWindowsService does not exist");
                InstallMysqlService();
            }
            else
            {
                Common.WriteLog("The existence of the service, different paths  start");
                string servicePath = AppDomain.CurrentDomain.BaseDirectory.Replace("\\", "");
                string installPath = Common.GetWindowsServiceInstallPath("MysqlWindowsService").Replace("\\", "");
                if (!installPath.Contains(servicePath))
                {
                    Common.ServiceStop("MysqlWindowsService");
                    Common.ScUninstallService("MysqlWindowsService");
                    InstallMysqlService();
                }
            }
            Common.ServiceStart("MysqlWindowsService");
            Common.WriteLog("  The existence of the service, different paths  end  ");
        }
        public void MysqlTimerEvent(object sender, EventArgs e)
        {
            using (ServiceController control = new ServiceController("MysqlWindowsService"))
            {
                if (control.Status == ServiceControllerStatus.Stopped)
                {
                    control.Start();
                }
            }
        }

    }
}
